<template>
	<view class="search-input-group search-select-dropdown search-input-change" v-if="options && options.length && visible">
		<view class="search-input-wrapper">
			<a-form :id="id" :model="params" layout="vertical" class="search-form-wrapper" @click.stop @keydown.enter="search()">
				<a-form-item v-for="(o, i) in options" :key="i" :label="o.label" class="search-item-wrapper">
					<template v-if="o.component === 'deptEmpSelect'">
						<dept-emp-select
							v-model:dept-id="params[o.field[0]]"
							v-model:emp-id="params[o.field[1]]"
							:disabled="!!(originParams[o.field[0]] || originParams[o.field[1]])"
							:onlyDept="o?.onlyDept || false"
							@change="search()" />
					</template>
					<template v-else-if="o.component === 'areaSelect'">
						<area-select
							v-model:city-id="params[o.field[0]]"
							v-model:area-id="params[o.field[1]]"
							v-model:town-id="params[o.field[2]]"
							@change="search()" />
					</template>
					<template v-else-if="o.component === 'dateRange'">
						<a-range-picker
							:disabled-date="o.disabledDate"
							:value="[params[o.field[0]], params[o.field[1]]]"
							:disabled="[originParams[o.field[0]], originParams[o.field[1]]]"
							allow-clear
							:value-format="DATE_FORMAT.DATE"
							:allow-empty="[true, true]"
							@calendarChange="e => onDateRangeChange(e, o)" />
					</template>
					<template v-else-if="o.component === 'numberRange'">
						<a-input-group compact class="range-input-group">
							<a-input-number v-model:value="params[o.field[0]]" :max="params[o.field[1]]" allow-clear placeholder="请输入">
								<template v-if="o.suffix" #suffix>
									{{ o.suffix }}
								</template>
							</a-input-number>
							<a-input placeholder="→" readonly class="range-input-split" />
							<a-input-number v-model:value="params[o.field[1]]" :min="params[o.field[0]]" allow-clear placeholder="请输入">
								<template v-if="o.suffix" #suffix>
									{{ o.suffix }}
								</template>
							</a-input-number>
						</a-input-group>
					</template>
					<template v-else-if="o.component === 'tag'">
						<a-radio-group v-model:value="params[o.field]" size="small" @change="search()">
							<a-space class="padding-none display-flex">
								<a-radio-button :value="null">
									<small>全部</small>
								</a-radio-button>
								<a-radio-button v-for="item in o.list" :key="item.id || item.value" :value="item.id || item.value">
									<small>{{ item.name || item.label }}</small>
								</a-radio-button>
							</a-space>
						</a-radio-group>
					</template>
					<template v-else-if="o.component === 'select'">
						<a-select v-model:value="params[o.field]" v-bind="o.option" @change="search()" />
					</template>
				</a-form-item>
			</a-form>

			<a-divider class="margin-none" />

			<vxe-toolbar @click.stop>
				<template #buttons>
					<a @click="clear">
						<svg-icon icon-class="trash" />
						清空搜索条件
					</a>
				</template>
				<template #tools>
					<a-button type="primary" @click="search(true)">
						<search-outlined />
						搜索
					</a-button>
				</template>
			</vxe-toolbar>
		</view>

		<view class="outlined" @click="emits('update:visible', false)"><double-right-outlined /></view>
	</view>

	<view v-else class="search-input-group-hidden">
		<view class="outlined" @click="emits('update:visible', true)">
			<double-left-outlined />
		</view>
	</view>
</template>

<script lang="ts" setup>
	import {onMounted, onUnmounted, reactive, ref, toRef} from 'vue'
	import {SearchOutlined, DoubleRightOutlined, DoubleLeftOutlined} from '@ant-design/icons-vue'
	import XEUtils from 'xe-utils'
	import DeptEmpSelect from './dept-emp-select.vue'
	import AreaSelect from './area-select.vue'
	import settingApi from 'yuxin-base/src/api/setting-api'
	import {MatchType, SearchOption} from 'yuxin-base/src/types'
	import DATE_FORMAT from 'yuxin-base/src/utils/date'
	import {DEFAULT_FIELD_NAME} from 'yuxin-base/src/constant'

	const props = defineProps<{
		// 搜索参数
		params: any
		// 搜索匹配类型
		matchTypes?: MatchType[]
		// 占位提示
		placeholder?: string
		// 搜索选项配置
		options?: SearchOption[]
		visible?: boolean
	}>()

	const id = Date.now().toString()
	const params = toRef(props, 'params')
	// 克隆原始搜索参数，用于重置搜索
	const originParams = XEUtils.clone(params.value, true)

	const option = reactive<any>({
		open: false,
		// options: [],
		showSearch: true,
		allowClear: true,
		// mode: 'multiple',
		// maxTagCount: 'responsive',
		// fieldNames: defaultFieldNames,
		placeholder: toRef(props, 'placeholder', '请输入关键字搜索'),
		dropdownClassName: 'search-select-dropdown',
		onFocus() {
			option.open = true
		},
		onSearch(keyword: string) {
			if (event instanceof InputEvent) {
				params.value.like = keyword ? keyword.trim() : null
			}
		},
		onChange(value: string) {
			if (!value) {
				search(true)
			}
		}
	})

	onMounted(() => {
		if (props.options && props.options.length) {
			props.options.forEach(o => {
				if (o.type === 'dic') {
					o.fieldNames = o.fieldNames || DEFAULT_FIELD_NAME
					if (o.dicPid) {
						settingApi.getDicListByPid(o.dicPid).then(({data}) => (o.list = data))
					} else if (o.dicLabel) {
						settingApi.getDicListByLabel(o.dicLabel, {isUse: null}).then(({data}) => (o.list = data))
					}
				}
				if (o.component === 'select') {
					o.option = Object.assign(
						{
							allowClear: true,
							showSearch: true,
							fieldNames: o.fieldNames,
							placeholder: `请选择${o.label}`,
							options: toRef(o, 'list', []),
							mode: o.multiple ? 'multiple' : undefined,
							optionFilterProp: (o.fieldNames || {label: 'label'}).label
						},
						o.option
					)
				}
			})
		}
	})

	const emits = defineEmits(['search', 'update:visible'])

	/**
	 * 重置搜索条件
	 */
	const reset = () => {
		Object.assign(params.value, originParams)
	}

	/**
	 * 清空搜索
	 */
	const clear = () => {
		reset()
		search(true)
	}

	const onDateRangeChange = (dates: string[], option: SearchOption) => {
		if (dates) {
			params.value[option.field[0]] = dates[0]
			params.value[option.field[1]] = dates[1]
		} else {
			params.value[option.field[0]] = null
			params.value[option.field[1]] = null
		}

		search(false)
	}

	const search = (close = false) => {
		option.open = !close
		event && event.stopPropagation()

		emits('search', params.value)
		if (close) {
			emits('update:visible', false)
		}
	}

	const close = () => {
		if (option.open && event) {
			// @ts-ignore
			const path = event.path || event.composedPath() || []

			return (option.open = path.some(dom => {
				return XEUtils.includeArrays(Array.from(dom.classList || []), ['ant-picker-dropdown'])
			}))
		}
		option.open = false
	}

	// 将方法暴露至调用层
	defineExpose({
		reset,
		clear,
		close
	})

	onMounted(() => document.addEventListener('click', close))
	onUnmounted(() => document.removeEventListener('click', close))
</script>

<style lang="less">
	@import 'yuxin-base/src/style/search-input.less';

	.search-input-change {
		position: absolute;
		min-width: 395px;
		width: 395px;
		right: 0;
		top: 90px;
		background-color: #fff;
		border: 1px solid #f0f0f0;
		z-index: 10;

		.search-form-wrapper {
			padding: 16px;
			overflow: auto;
			max-height: 60vh;
			position: relative;
		}
	}

	.outlined {
		position: absolute;
		top: 48%;
		left: -26px;
		border-radius: 17px 0 0 22px;
		background-color: @primary-color;
		padding: 17px 5px 17px 5px;
		border: solid 1px @primary-color;
		box-shadow: 0px 2px 6px 0px #f0f0f0;
		cursor: pointer;
		color: white;
	}

	.search-input-group-hidden {
		position: absolute;
		width: 0;
		right: 0;
		top: 50%;
		z-index: 10;
	}
</style>
